home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 684 / 684.xpi / chrome / fireftp.jar / content / js / connection / dataSocket.js < prev    next >
Text File  |  2009-06-15  |  18KB  |  475 lines

  1. function ftpDataSocketMozilla(controlHost, controlPort, security, proxy, host, port, compress, id, observer, cert, asciiMode) {
  2.   this.transportService  = Components.classes["@mozilla.org/network/socket-transport-service;1"].getService(Components.interfaces.nsISocketTransportService);
  3.   this.proxyService      = Components.classes["@mozilla.org/network/protocol-proxy-service;1"].getService  (Components.interfaces.nsIProtocolProxyService);
  4.   this.dnsService        = Components.classes["@mozilla.org/network/dns-service;1"].getService             (Components.interfaces.nsIDNSService);
  5.   this.eventTarget       = Components.classes["@mozilla.org/thread-manager;1"].getService                  ().currentThread;
  6.   this.security          = security || false;
  7.   this.host              = (security ? controlHost : (host || ""));
  8.   this.port              = port     || -1;
  9.   this.proxyType         = proxy ? proxy.proxyType : "";
  10.   this.proxyHost         = proxy ? proxy.proxyHost : "";
  11.   this.proxyPort         = proxy ? proxy.proxyPort : -1;
  12.   this.useCompression    = compress;
  13.   this.dataListener      = new dataListener();
  14.   this.progressEventSink = new progressEventSink();
  15.   this.id                = id;
  16.   this.observer          = observer;
  17.   this.asciiMode         = asciiMode;
  18.  
  19.   if (security) {
  20.     try {
  21.       this.certOverride = Components.classes["@mozilla.org/security/certoverride;1"].getService(Components.interfaces.nsICertOverrideService);
  22.       var hashAlg = {};  var fingerprint = {};  var overrideBits = {};  var isTemporary = {};
  23.       var ok = this.certOverride.getValidityOverride(controlHost, controlPort, hashAlg, fingerprint, overrideBits, isTemporary);
  24.  
  25.       this.certOverride.rememberValidityOverride(this.host, port, cert, overrideBits.value, true);
  26.     } catch (ex) {
  27.       if (this.observer) {
  28.         this.observer.onDebug(ex);
  29.       }
  30.     }
  31.   }
  32. }
  33.  
  34. ftpDataSocketMozilla.prototype = {
  35.   dataTransport : null,
  36.   dataInstream  : null,
  37.   dataOutstream : null,
  38.   fileInstream  : null,
  39.   serverSocket  : null,
  40.  
  41.   listData      : "",
  42.   finished      : true,
  43.  
  44.   emptyFile     : false,                                                                    // XXX empty files are (still) special cases
  45.  
  46.   connect : function(write, localPath, fileTotalBytes, filePartialBytes, activeTransport) {
  47.     try {
  48.       if (activeTransport) {
  49.         this.dataTransport = activeTransport;
  50.       } else {
  51.         var proxyInfo = this.proxyType == "" ? null : this.proxyService.newProxyInfo(this.proxyType, this.proxyHost, this.proxyPort, 0, 30, null);
  52.  
  53.         if (this.security) {
  54.           this.dataTransport = this.transportService.createTransport(["ssl"], 1, this.host, this.port, proxyInfo);
  55.         } else {
  56.           this.dataTransport = this.transportService.createTransport(null,    0, this.host, this.port, proxyInfo);
  57.         }
  58.       }
  59.  
  60.       this.finished = false;
  61.  
  62.       if (write)  {                                                                         // upload
  63.         this.dataOutstream  = this.dataTransport.openOutputStream(0, 0, -1);
  64.         var file;
  65.  
  66.         try {
  67.           file              = localFile.init(localPath);
  68.           this.fileInstream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance();
  69.           this.fileInstream.QueryInterface(Components.interfaces.nsIFileInputStream);
  70.           this.fileInstream.init(file, 0x01, 0644, 0);
  71.           this.fileInstream.QueryInterface(Components.interfaces.nsISeekableStream);
  72.           this.fileInstream.seek(0, filePartialBytes);                                      // append or not to append
  73.         } catch (ex) {
  74.           if (this.observer) {
  75.             this.observer.onDebug(ex);
  76.           }
  77.  
  78.           if (this.observer) {
  79.             this.observer.onError(gStrbundle.getFormattedString("failedUpload", [localPath]));
  80.           }
  81.  
  82.           this.kill();
  83.           return;
  84.         }
  85.  
  86.         var binaryOutstream = Components.classes["@mozilla.org/binaryoutputstream;1"].createInstance(Components.interfaces.nsIBinaryOutputStream);
  87.         binaryOutstream.setOutputStream(this.dataOutstream);
  88.  
  89.         this.dataInstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
  90.         this.dataInstream.setInputStream(this.fileInstream);
  91.  
  92.         this.progressEventSink.parent        = this;
  93.         this.progressEventSink.localPath     = localPath;
  94.         this.progressEventSink.sendPrevSent  = 0;
  95.         this.progressEventSink.timeStart     = new Date();
  96.         this.progressEventSink.bytesTotal    = file.fileSize;
  97.         this.progressEventSink.bytesUploaded = this.useCompression ? 0 : filePartialBytes;
  98.         this.progressEventSink.bytesPartial  = filePartialBytes;
  99.         this.progressEventSink.dataInstream  = this.dataInstream;
  100.         this.progressEventSink.dataOutstream = binaryOutstream;
  101.         this.progressEventSink.fileInstream  = this.fileInstream;
  102.         this.progressEventSink.asciiMode     = this.asciiMode;
  103.         this.emptyFile                       = !file.fileSize;
  104.  
  105.         this.dataTransport.setEventSink(this.progressEventSink, this.eventTarget);
  106.  
  107.         if (this.useCompression && file.fileSize) {                                         // never as elegant as downloading :(
  108.           this.progressEventSink.compressStream = true;
  109.  
  110.           var streamConverter = Components.classes["@mozilla.org/streamconv;1?from=uncompressed&to=deflate"].createInstance(Components.interfaces.nsIStreamConverter);
  111.           streamConverter.asyncConvertData("uncompressed", "deflate", this.progressEventSink, null);
  112.  
  113.           var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
  114.           pump.init(this.dataInstream, -1, -1, 0, 0, false);
  115.           pump.asyncRead(streamConverter, null);
  116.         } else {
  117.           var dataBuffer = this.dataInstream.readBytes(this.dataInstream.available() < 4096 ? this.dataInstream.available() : 4096);
  118.  
  119.           var diff = dataBuffer.length;
  120.  
  121.           if (this.asciiMode) {
  122.             dataBuffer = dataBuffer.replace(/(^|[^\r])\n/g, "$1\r\n");
  123.           }
  124.  
  125.           this.progressEventSink.bytesTotal += dataBuffer.length - diff;
  126.  
  127.           this.progressEventSink.dataOutstream.writeBytes(dataBuffer, dataBuffer.length);
  128.         }
  129.       } else {                                                                              // download
  130.         this.listData                     = "";
  131.         var dataStream                    = this.dataTransport.openInputStream(0, 0, 0);
  132.  
  133.         var streamConverter;
  134.         this.dataInstream                 = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
  135.         if (this.useCompression) {
  136.           streamConverter = Components.classes["@mozilla.org/streamconv;1?from=deflate&to=uncompressed"].createInstance(Components.interfaces.nsIStreamConverter);
  137.             streamConverter.asyncConvertData("deflate", "uncompressed", this.dataListener, null);
  138.         } else {
  139.           this.dataInstream.setInputStream(dataStream);
  140.         }
  141.  
  142.         this.dataListener.parent          = this;
  143.         this.dataListener.localPath       = localPath;
  144.         this.dataListener.dataInstream    = this.dataInstream;
  145.         this.dataListener.data            = "";
  146.         this.dataListener.file            = "";
  147.         this.dataListener.fileOutstream   = "";
  148.         this.dataListener.binaryOutstream = "";
  149.         this.dataListener.bytesTotal      = fileTotalBytes   || 0;
  150.         this.dataListener.bytesDownloaded = filePartialBytes || 0;
  151.         this.dataListener.bytesPartial    = filePartialBytes || 0;
  152.         this.dataListener.timeStart       = new Date();
  153.         this.dataListener.dataBuffer      = "";
  154.         this.dataListener.isNotList       = localPath != null;
  155.         this.dataListener.useCompression  = this.useCompression;
  156.         this.dataListener.asciiMode       = this.asciiMode;
  157.  
  158.         var pump = Components.classes["@mozilla.org/network/input-stream-pump;1"].createInstance(Components.interfaces.nsIInputStreamPump);
  159.         pump.init(dataStream, -1, -1, 0, 0, false);
  160.         pump.asyncRead(this.useCompression ? streamConverter : this.dataListener, null);
  161.       }
  162.  
  163.     } catch(ex) {
  164.       if (this.observer) {
  165.         this.observer.onDebug(ex);
  166.       }
  167.  
  168.       if (this.observer) {
  169.         this.observer.onError(gStrbundle.getString("errorDataConn"));
  170.       }
  171.  
  172.       return;
  173.     }
  174.   },
  175.  
  176.   createServerSocket : function(activeInfo) {
  177.     try {
  178.       var ipAddress      = this.dnsService.resolve(this.dnsService.myHostName, false).getNextAddrAsString();
  179.       var re             = /\x2e/g;
  180.       this.serverSocket  = Components.classes["@mozilla.org/network/server-socket;1"].createInstance(Components.interfaces.nsIServerSocket);
  181.  
  182.       var self = this;
  183.       var serverListener = {
  184.         onSocketAccepted : function(serv, transport) {
  185.           if (activeInfo.cmd == "LIST") {
  186.             self.connect(false, null,                  0,                    0,                       transport);
  187.           } else if (activeInfo.cmd == "RETR") {
  188.             self.connect(false, activeInfo.localPath, activeInfo.totalBytes, 0,                       transport);
  189.           } else if (activeInfo.cmd == "REST") {
  190.             self.connect(false, activeInfo.localPath, activeInfo.totalBytes, activeInfo.partialBytes, transport);
  191.           } else if (activeInfo.cmd == "STOR") {
  192.             self.connect(true,  activeInfo.localPath, 0,                     0,                       transport);
  193.           } else if (activeInfo.cmd == "APPE") {
  194.             self.connect(true,  activeInfo.localPath, 0,                     activeInfo.partialBytes, transport);
  195.           }
  196.         },
  197.  
  198.         onStopListening : function(serv, status) { }
  199.       };
  200.  
  201.       this.serverSocket.init(this.port, false, -1);
  202.       this.serverSocket.asyncListen(serverListener);
  203.  
  204.       if (activeInfo.ipType == "IPv4" && ipAddress.indexOf(':') == -1) {
  205.         return ipAddress.replace(re, ",") + "," + parseInt(this.serverSocket.port / 256) + "," + this.serverSocket.port % 256;
  206.       } else {
  207.         return (ipAddress.indexOf(':') != -1 ? "|2|" : "|1|") + ipAddress + "|" + this.serverSocket.port + "|";
  208.       }
  209.     } catch (ex) {
  210.       if (this.observer) {
  211.         this.observer.onDebug(ex);
  212.       }
  213.  
  214.       if (this.observer) {
  215.         this.observer.onError(gStrbundle.getString("errorDataConn"));
  216.       }
  217.  
  218.       return null;
  219.     }
  220.   },
  221.  
  222.   kill : function(override) {
  223.     this.progressEventSink.bytesTotal = 0;                                                  // stop uploads
  224.     this.dataListener.bytesTotal      = 0;                                                  // stop downloads
  225.  
  226.     try {
  227.       if (this.dataInstream && this.dataInstream.close) {
  228.         this.dataInstream.close();
  229.       }
  230.     } catch(ex) { }
  231.  
  232.     try {
  233.       if ((!this.emptyFile || override) && this.dataOutstream && this.dataOutstream.flush) {
  234.         this.dataOutstream.flush();
  235.       }
  236.  
  237.       if ((!this.emptyFile || override) && this.dataOutstream && this.dataOutstream.close) {
  238.         this.dataOutstream.close();
  239.       }
  240.     } catch(ex) { }
  241.  
  242.     try {
  243.       if ((!this.emptyFile || override) && this.fileInstream && this.fileInstream.close) {
  244.         this.fileInstream.close();
  245.       }
  246.     } catch(ex) { }
  247.  
  248.     try {
  249.       if ((!this.emptyFile || override)) {                                                  // XXX empty files are (still) special cases
  250.         if (this.dataTransport && this.dataTransport.close) {
  251.           this.dataTransport.close("Finished");
  252.         }
  253.       }
  254.     } catch(ex) { }
  255.  
  256.     try {
  257.       if (this.dataListener.binaryOutstream && this.dataListener.binaryOutstream.close) {
  258.         this.dataListener.binaryOutstream.close();
  259.       }
  260.     } catch(ex) { }
  261.  
  262.     try {
  263.       if (this.dataListener.fileOutstream && this.dataListener.fileOutstream.close) {
  264.         this.dataListener.fileOutstream.close();
  265.       }
  266.     } catch(ex) { }
  267.  
  268.     try {
  269.       if (this.serverSocket && this.serverSocket.close) {
  270.         this.serverSocket.close();
  271.       }
  272.     } catch(ex) { }
  273.  
  274.     this.progressEventSink.parent     = null;                                               // stop memory leakage!
  275.     this.dataListener.parent          = null;                                               // stop memory leakage!
  276.  
  277.     this.finished  = true;
  278.  
  279.     if (this.security) {
  280.       try {
  281.         this.certOverride.clearValidityOverride(this.host, this.port);
  282.       } catch (ex) {
  283.         if (this.observer) {
  284.           this.observer.onDebug(ex);
  285.         }
  286.       }
  287.     }
  288.   }
  289. };
  290.  
  291. function dataListener() { }
  292.  
  293. dataListener.prototype = {
  294.   parent           : null,
  295.   localPath        : "",
  296.   dataInstream     : "",
  297.   data             : "",
  298.   file             : "",
  299.   fileOutstream    : "",
  300.   binaryOutstream  : "",
  301.   bytesTotal       : 0,
  302.   bytesDownloaded  : 0,
  303.   bytesPartial     : 0,
  304.   timeStart        : new Date(),
  305.   dataBuffer       : "",
  306.   isNotList        : false,
  307.   useCompression   : false,
  308.   asciiMode        : false,
  309.  
  310.   onStartRequest : function(request, context) {
  311.     if (this.isNotList) {
  312.       this.timeStart = new Date();
  313.  
  314.       try {
  315.         this.file          = localFile.init(this.localPath);
  316.         this.fileOutstream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
  317.  
  318.         if (this.bytesPartial) {
  319.           this.fileOutstream.init(this.file, 0x04 | 0x10, 0644, 0);
  320.         } else {
  321.           this.fileOutstream.init(this.file, 0x04 | 0x08 | 0x20, 0644, 0);
  322.         }
  323.  
  324.         this.binaryOutstream = Components.classes["@mozilla.org/binaryoutputstream;1"].createInstance(Components.interfaces.nsIBinaryOutputStream);
  325.         this.binaryOutstream.setOutputStream(this.fileOutstream);
  326.       } catch (ex) {
  327.         this.failure(ex);
  328.       }
  329.     }
  330.   },
  331.  
  332.   onStopRequest : function(request, context, status) {
  333.     if (!this.isNotList && this.parent) {
  334.       this.parent.listData = this.data;
  335.     }
  336.  
  337.     if (this.parent) {
  338.       this.parent.kill();
  339.     }
  340.   },
  341.  
  342.   onDataAvailable : function(request, context, inputStream, offset, count) {
  343.     if (this.useCompression) {
  344.       this.dataInstream.setInputStream(inputStream);
  345.     }
  346.  
  347.     if (this.isNotList) {
  348.       try {
  349.         this.dataBuffer = this.dataInstream.readBytes(count);
  350.  
  351.         var length = this.dataBuffer.length;
  352.  
  353.         if (this.asciiMode && this.getPlatform() != "windows") {
  354.           this.dataBuffer = this.dataBuffer.replace(/\r\n/g, '\n');
  355.         }
  356.  
  357.         this.binaryOutstream.writeBytes(this.dataBuffer, this.dataBuffer.length)
  358.         this.bytesDownloaded += length;
  359.       } catch (ex) {
  360.         this.failure(ex);
  361.       }
  362.     } else {
  363.       this.data += this.dataInstream.readBytes(count);
  364.     }
  365.   },
  366.  
  367.   failure : function(ex) {
  368.     if (this.parent.observer) {
  369.       this.parent.observer.onDebug(ex);
  370.     }
  371.  
  372.     if (this.parent.observer) {
  373.       this.parent.observer.onError(gStrbundle.getFormattedString("failedSave", [this.localPath]));
  374.     }
  375.  
  376.     this.parent.kill();
  377.   },
  378.  
  379.   getPlatform : function() {
  380.     var platform = navigator.platform.toLowerCase();
  381.  
  382.     if (platform.indexOf('linux') != -1) {
  383.       return 'linux';
  384.     }
  385.  
  386.     if (platform.indexOf('mac') != -1) {
  387.       return 'mac';
  388.     }
  389.  
  390.     return 'windows';
  391.   }
  392. };
  393.  
  394. function progressEventSink() { }
  395.  
  396. progressEventSink.prototype = {
  397.   parent         : null,
  398.   localPath      : "",
  399.   bytesTotal     : 0,
  400.   sendPrevSent   : 0,
  401.   bytesUploaded  : 0,
  402.   timeStart      : new Date(),
  403.   bytesPartial   : 0,
  404.   dataOutstream  : null,
  405.   fileInstream   : null,
  406.   compressFirst  : true,
  407.   compressStream : false,
  408.   compressTotal  : 0,
  409.   compressDone   : false,
  410.   compressBuffer : "",
  411.   asciiMode      : false,
  412.  
  413.   onStartRequest  : function(request, context) { },
  414.   onStopRequest   : function(request, context, status) {
  415.     this.compressDone = true;
  416.   },
  417.  
  418.   onDataAvailable : function(request, context, inputStream, offset, count) {
  419.     try {
  420.       var dataInstream = Components.classes["@mozilla.org/binaryinputstream;1"].createInstance(Components.interfaces.nsIBinaryInputStream);
  421.       dataInstream.setInputStream(inputStream);
  422.       this.compressTotal  += count;
  423.       this.compressBuffer += dataInstream.readBytes(count);
  424.  
  425.       if (this.compressFirst) {
  426.         this.compressFirst = false;
  427.         this.dataOutstream.writeBytes(this.compressBuffer, this.compressBuffer.length);
  428.         this.compressBuffer = "";
  429.       }
  430.     } catch (ex) {
  431.       this.failure(ex);
  432.     }
  433.   },
  434.  
  435.   onTransportStatus : function (transport, status, progress, progressMax) {
  436.     this.bytesUploaded += progress - this.sendPrevSent;
  437.     this.sendPrevSent   = progress;
  438.  
  439.     if ((!this.compressStream && this.bytesUploaded == this.bytesTotal)
  440.       || (this.compressStream && this.compressDone && this.bytesUploaded == this.compressTotal)) {  // finished writing
  441.       this.parent.kill();                                                                           // can't rely on this.fileInstream.available() - corrupts uploads
  442.       return;
  443.     }
  444.  
  445.     if (this.compressStream) {
  446.       this.dataOutstream.writeBytes(this.compressBuffer, this.compressBuffer.length);
  447.       this.compressBuffer = "";
  448.     } else {
  449.       var dataBuffer = this.dataInstream.readBytes(this.dataInstream.available() < 4096 ? this.dataInstream.available() : 4096);
  450.  
  451.       var diff = dataBuffer.length;
  452.  
  453.       if (this.asciiMode) {
  454.         dataBuffer = dataBuffer.replace(/(^|[^\r])\n/g, "$1\r\n");
  455.       }
  456.  
  457.       this.bytesTotal += dataBuffer.length - diff;
  458.  
  459.       this.dataOutstream.writeBytes(dataBuffer, dataBuffer.length);
  460.     }
  461.   },
  462.  
  463.   failure : function(ex) {
  464.     if (this.parent.observer) {
  465.       this.parent.observer.onDebug(ex);
  466.     }
  467.  
  468.     if (this.parent.observer) {
  469.       this.parent.observer.onError(gStrbundle.getFormattedString("failedUpload", [this.localPath]));
  470.     }
  471.  
  472.     this.parent.kill();
  473.   }
  474. };
  475.